package service

import (
	"context"
	"time"

	"admin_template/bff/admin/hertz_gen/base"
	"admin_template/bff/admin/internal/base/data"
	"admin_template/bff/admin/internal/pkg/utils"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
	"github.com/pkg/errors"
)

type Face interface {
	StateUpdate(ctx context.Context,
		info *base.StateUpdateRequest) error
	Add(context.Context, any) error
	UpdateInfo(context.Context, any) error
	List(context.Context,
		any) (int64, int64, int64, []any, error)
	All(context.Context,
		any) ([]any, error)
	Init(context.Context) error
	One(context.Context, int) (any, error)
}

type Service struct {
	*data.Data
	EnforcerRepo EnforcerRepo
}

func NewService(d *data.Data,
	enforcerRepo EnforcerRepo) *Service {
	return &Service{d, enforcerRepo}
}
func (s *Service) BindAndValidate(ctx context.Context,
	c *app.RequestContext, obj interface{}) bool {
	err := c.BindAndValidate(obj)
	if err != nil {
		utils.ReplyWithBindErr(c, ctx, s.CtxLogger, err)
		return false
	}
	return true
}

func (s *Service) CheckUserUUID(ctx context.Context,
	c *app.RequestContext, obj interface{}) (string, bool) {
	err := c.BindAndValidate(obj)
	if err != nil {
		utils.ReplyWithBindErr(c, ctx, s.CtxLogger, err)
		return "", false
	}
	userUUID := s.UserUUID(c)
	if userUUID == "" {
		c.AbortWithStatus(consts.StatusFound)
		return "", false
	}
	return userUUID, true
}

func (s *Service) RecoveryHandler(ctx context.Context, c *app.RequestContext, err interface{}, stack []byte) {
	s.CtxLogger.CtxErrorf(ctx, "[Recovery] err=%v\nstack=%s", err, stack)
	s.CtxLogger.CtxInfof(ctx, "Client: %s", c.Request.Header.UserAgent())
	msg := string(stack)
	if err.(error) != nil {
		msg = err.(error).Error()
	}
	reply := base.BaseReply{
		Code: base.ErrCode_Fail,
		Msg:  msg,
	}
	utils.Reply(c, consts.StatusOK, &reply)
	c.Abort()

}
func (s *Service) GetSk(c context.Context,
	ctx *app.RequestContext,
	ak string,
	timestamp int64) (context.Context, string, bool, error) {
	if s.Config.SystemConfig.HttpSignExpire > 0 {
		//时间过期
		timeUnix := time.Now().Unix()
		if timestamp < timeUnix-s.Config.SystemConfig.HttpSignExpire || timestamp > timeUnix {
			return c, s.Config.ServerOption.Auth.SK, false, errors.New("http sign time expire")
		}
	}
	return c, s.Config.ServerOption.Auth.SK, false, nil
}
